//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;

using CommunityServer.Components;

namespace CommunityServer.Blogs.Components
{
    /// <summary>
    /// Summary description for BlogConfiguration.
    /// </summary>
    [Serializable]   
    public class Weblog : Section
    {

		#region Public 

        public string Email
        {
            get{return GetExtendedAttribute("email");}
            set{SetExtendedAttribute("email", value);}
        }

        public string RssLanguage
        {
            get{return GetExtendedAttribute("rssLanguage");}
            set{SetExtendedAttribute("rssLanguage", value);}
        }
		
        public string News
        {
            get{return GetExtendedAttribute("news");}
            set{SetExtendedAttribute("news", value);}
        }


		public bool EnableAggBugs
		{
			get {  return GetBool("EnableAggBugs",true); }
			set{ SetExtendedAttribute("EnableAggBugs",value.ToString()); }
		}

        public bool AutoNamePosts
        {
            get {  return GetBool("AutoNamePosts",true); }
            set{ SetExtendedAttribute("AutoNamePosts",value.ToString()); }
        }

        public bool EnableRss
        {
            get {  return GetBool("EnableRss",true); }
            set{ SetExtendedAttribute("EnableRss",value.ToString()); }
        }

        public bool EnableAtom
        {
            get {  return GetBool("EnableAtom",true); }
            set{ SetExtendedAttribute("EnableAtom",value.ToString()); }
        }

		public bool EnableTagsRss
		{
			get { return GetBool("EnableTagsRss", true); }
			set { SetExtendedAttribute("EnableTagsRss", value.ToString()); }
		}
		
		public bool EnableAbout
        {
            get {  return GetBool("EnableAbout",false); }
            set{ SetExtendedAttribute("EnableAbout",value.ToString()); }
        }

        public bool SyndicateExternalLinks
        {
            get { return GetBool("SyndicateExternalLinks", false); }
            set { SetExtendedAttribute("SyndicateExternalLinks", value.ToString()); }
        }

		/// <summary>
		/// The type of feedback the owner should receive notification for.
		/// </summary>
		public FeedbackNotificationType FeedbackNotificationType
		{
			get{ return (FeedbackNotificationType)GetInt("feedbackNotificationType", (int)FeedbackNotificationType.None); }
			set{ this.SetExtendedAttribute("feedbackNotificationType",((int)value).ToString()); }
		}

		public bool EnableAllOwnerNotification
		{
			get{ return GetBool("enableAllOwnerNotification", false); }
			set{ SetExtendedAttribute("enableAllOwnerNotification", value.ToString()); }

		}


		#region Cross Posting
		/// <summary>
		/// A list of Urls that posts can be cross-posted to using the MetaWeblog API
		/// </summary>
		public RemoteMetaBlogSettings[] CrossPostingSettings
		{
			get
			{
				RemoteMetaBlogSettings[] settings;
				settings = (RemoteMetaBlogSettings[])Serializer.ConvertToObject(GetExtendedAttribute("remoteMetaBlogSettings"), typeof(RemoteMetaBlogSettings[]));
				return settings;
			}
			set
			{
				if(value != null)
					SetExtendedAttribute("remoteMetaBlogSettings", Serializer.ConvertToString(value));
				else
					SetExtendedAttribute("remoteMetaBlogSettings",null);
			}
		}
		#endregion

        #region Post Globals/Overrides


        public bool EnableTrackbacksOverride
        {
            get{return GetBool("EnableTrackbacksOverride", true);}
            set{ SetExtendedAttribute("EnableTrackbacksOverride",value.ToString()); }
        }

        public bool EnableCommentsOverride
        {
            get {  return GetBool("EnableCommentsOverride",true); }
            set{ SetExtendedAttribute("EnableCommentsOverride",value.ToString()); }
        }

		public bool EnableRssCommentsOverride
		{
			get	{return GetBool("EnableRssCommentsOverride", false);}
			set {SetExtendedAttribute("EnableRssCommentsOverride", value.ToString()); }
		}

        public bool EnableRatingsOverride
        {
            get{return GetBool("EnableRatingsOverride", true);}
            set{ SetExtendedAttribute("EnableRatingsOverride",value.ToString()); }
        }

        public CommentModerationType ModerationTypeOverride
        {
            //We need to support previous .Text configuration options. 
            //If IsModerated = true, we will return CommentModerationType.All since this was the same .Text behavior
            //If a user updates this property, we will set IsModerated to false, which will be an indication that we will 
            //no longer need to honor the .Text concept. 

            get
            {
                return (CommentModerationType)Enum.Parse(typeof(CommentModerationType),GetString("ModerationTypeOverride","Ignore"),false);
				
            }
            set
            {
                SetExtendedAttribute("ModerationTypeOverride",value.ToString());
            }
		
        }

        #endregion

        #region Default Settings

        public CommentModerationType ModerationTypeDefault
        {
            //We need to support previous .Text configuration options. 
            //If IsModerated = true, we will return CommentModerationType.All since this was the same .Text behavior
            //If a user updates this property, we will set IsModerated to false, which will be an indication that we will 
            //no longer need to honor the .Text concept. 

            get
            {
                if(IsModerated)
                    return CommentModerationType.All;

                return (CommentModerationType)Enum.Parse(typeof(CommentModerationType),GetString("CommentModerationType","None"),false);
				
            }
            set
            {
                this.IsModerated = false;
                SetExtendedAttribute("CommentModerationType",value.ToString());
            }
		
        }

        public bool EnableCommentsDefault
        {
            get {  return GetBool("EnableComments",true); }
            set{ SetExtendedAttribute("EnableComments",value.ToString()); }
        }

		public bool EnableRssCommentsDefault
		{
			get	{return GetBool("EnableRssComments", false);}
			set {SetExtendedAttribute("EnableRssComments", value.ToString()); }
		}

        public bool EnableRatingsDefault
        {
            get{return GetBool("EnableRatings", true);}
            set{ SetExtendedAttribute("EnableRatings",value.ToString()); }
        }

        public bool EnableTrackbacksDefault
        {
            get{return GetBool("EnableTrackbacks", true);}
            set{ SetExtendedAttribute("EnableTrackbacks",value.ToString()); }
        }

        public bool EnableCommunityParticipationDefault
        {
            get{ return GetDefaultPostConfig(BlogPostConfig.IsCommunityAggregated);}
            set{  SetDefaultPostConfig(BlogPostConfig.IsCommunityAggregated,value); }
        }

        public bool EnablePostAggregationDefault
        {
            get{ return GetDefaultPostConfig(BlogPostConfig.IsAggregated);}
            set{  SetDefaultPostConfig(BlogPostConfig.IsAggregated,value); }
        }

        public bool SyndicateExcerptDefault
        {
            get{ return GetDefaultPostConfig(BlogPostConfig.SyndicateExcerpt);}
            set{  SetDefaultPostConfig(BlogPostConfig.SyndicateExcerpt,value); }
        }

		public bool EnableCrossPostingDefault
		{
			get{ return GetBool("enableCrossPosting", false); }
			set{ this.SetExtendedAttribute("enableCrossPosting",value.ToString()); }
		}

        public BlogPostConfig DefaultPostConfig
        {
            get{ return (BlogPostConfig) GetInt("DefaultPostConfig", 3); }
            set { SetExtendedAttribute("DefaultPostConfig", ((int)value).ToString());}
        }

        protected void SetDefaultPostConfig(BlogPostConfig bpc, bool isSelected)
        {
            DefaultPostConfig = PostConfigHelper.SetPostConfig(DefaultPostConfig,bpc,isSelected);
        }

          protected bool GetDefaultPostConfig(BlogPostConfig bpc)
        {
            return PostConfigHelper.IsPostConfigSelected(DefaultPostConfig,bpc);
        }
        #endregion

        public bool EnableContact
        {
            get
            {
                return GetBool("EnableContact", true);
            }
            set{ SetExtendedAttribute("EnableContact",value.ToString()); }
        }


        public bool EnablePings
        {
            get
            {
                return GetBool("EnablePings",true);
            }
            set{ SetExtendedAttribute("EnablePings",value.ToString()); }
        }

        public string[] PingUrls
        {
            get
            {
                string[] pings = null;
                if(EnablePings)
                {
                    string p  = GetExtendedAttribute("PingUrls");
                    if(p != null && p.Length > 0)
                        pings = p.Split(',');
                }

                return pings;
            }
            set
            {
                if(value != null)
                    SetExtendedAttribute("PingUrls",string.Join(",",value));
                else
                    SetExtendedAttribute("PingUrls",null);
            }
        }

        public bool ShowContact
        {
            get
            {
                return EnableContact && !Globals.IsNullorEmpty(this.Email);
            }
        }

        public int CommentExpirationDays
        {
            get
            {
                string i = GetExtendedAttribute("ced");
                if(i == null || i.Trim().Length == 0)
                    return 999999;

                return Int32.Parse(i);
            }
            set{ SetExtendedAttribute("ced",value.ToString()); }
        }

        public string AboutTitle
        {
            get{return GetString("aboutTitle", "About " + this.Name);}
            set{SetExtendedAttribute("aboutTitle", value);}
        }

        public string AboutDescription
        {
            get{return GetExtendedAttribute("aboutDescription");}
            set{SetExtendedAttribute("aboutDescription", value);}
        }

        public bool HasAbout
        {
            get{ return !Globals.IsNullorEmpty(AboutTitle) || !Globals.IsNullorEmpty(AboutDescription); }
        }


		public string RawAdditionalHeader 
		{
			get{return GetExtendedAttribute("rawAdditionalHeader");}
			set{SetExtendedAttribute("rawAdditionalHeader", value);}
		}

		public string ExternalFeedUrl
		{
			get { return GetExtendedAttribute("externalFeedUrl"); }
			set { SetExtendedAttribute("externalFeedUrl", value); }
		}

		public int ModeratedFeedbackNotificationThreshold
		{
			get { return this.GetInt("modFeedbackNotifyThreshold", 0); }
			set { SetExtendedAttribute("modFeedbackNotifyThreshold", value.ToString()); }
		}

		public bool ModeratedFeedbackNotificationSent
		{
			get { return this.GetBool("modFeedbackNotifySent", false); }
			set { SetExtendedAttribute("modFeedbackNotifySent", value.ToString()); }
		}
		
		#endregion

        #region Permissions
        /// <summary>
        /// Returns a new instance of BlogPermission
        /// </summary>
        public override PermissionBase DefaultRolePermission
        {
            get
            {
                return new WeblogPermission();
            }
        }

        private AccessCheckDelegate _acd = null;

        /// <summary>
        /// Returns the delegate/method signature used to check the current users access
        /// to the requested blog
        /// </summary>
        public override AccessCheckDelegate AccessCheck
        {
            get
            {
                if(_acd == null)
                    _acd =  new AccessCheckDelegate(WeblogPermission.AccessCheck);

                return _acd;
            }
        }

        private ValidatePermissionsDelegate _vpd = null;
        /// <summary>
        /// Returns the delegate/method signature used to validate the current users
        /// permissions for a blog.
        /// </summary>
        public override ValidatePermissionsDelegate ValidatePermissions
        {
            get
            {
                if(_vpd == null)
                    _vpd = new ValidatePermissionsDelegate(WeblogPermission.Validate);

                return _vpd;
            }
        }

        public override bool IsPrivate
        {
            get
            {
                User user = Users.GetAnonymousUser(true);
                if(user != null)
                {
                    return !Permissions.ValidatePermissions(this,Permission.View,user);
                }
                return true;
            }

        }

        #endregion

        #region Recent Data
        private string _mostRecentPostName;
        /// <summary>
        /// Property MostRecentPostName (string)
        /// </summary>
        public string MostRecentPostName
        {
            get {  return this._mostRecentPostName; }
            set {  this._mostRecentPostName = value; }
        }


        private int _mostRecentArticleID;
        /// <summary>
        /// Property MostRecentArticleID (int)
        /// </summary>
        public int MostRecentArticleID
        {
            get {  return this._mostRecentArticleID; }
            set {  this._mostRecentArticleID = value; }
        }

        private DateTime _mostRecentArticleDate;
        /// <summary>
        /// Property MostRecentArticleDate (DateTime)
        /// </summary>
        public DateTime MostRecentArticleDate
        {
            get {  return this._mostRecentArticleDate; }
            set {  this._mostRecentArticleDate = value; }
        }

        private string _mostRecentArticleName;
        /// <summary>
        /// Property MostRecentArticleName (string)
        /// </summary>
        public string MostRecentArticleName
        {
            get {  return this._mostRecentArticleName; }
            set {  this._mostRecentArticleName = value; }
        }

		string mostRecentArticleSubject = ""; // most recent post subject
		/// <summary>
		/// Specifies the subject (title) of the most recent article.
		/// </summary>
		public String MostRecentArticleSubject 
		{
			get { return mostRecentArticleSubject; }
			set 
			{
				mostRecentArticleSubject = value;
			}
		}


        private int _mostRecentArticleAuthorID;
        /// <summary>
        /// Property MostRecentArticleAuthorID (int)
        /// </summary>
        public int MostRecentArticleAuthorID
        {
            get {  return this._mostRecentArticleAuthorID; }
            set {  this._mostRecentArticleAuthorID = value; }
        }

        private string _mostRecentArticleAuthorName;
        /// <summary>
        /// Property MostRecentArticleAuthorName (string)
        /// </summary>
        public string MostRecentArticleAuthor
        {
            get {  return this._mostRecentArticleAuthorName; }
            set {  this._mostRecentArticleAuthorName = value; }
        }

        #endregion

        #region Counts
        private int _postCount;
        /// <summary>
        /// Property PostCount (int)
        /// </summary>
        public int PostCount
        {
            get {  return this._postCount; }
            set {  this._postCount = value; }
        }

        private int _articleCount;
        /// <summary>
        /// Property ArticleCount (int)
        /// </summary>
        public int ArticleCount
        {
            get {  return this._articleCount; }
            set {  this._articleCount = value; }
        }

        private int _commentCount;
        /// <summary>
        /// Property CommentCount (int)
        /// </summary>
        public int CommentCount
        {
            get {  return this._commentCount; }
            set {  this._commentCount = value; }
        }

        private int _trackbackCount;
        /// <summary>
        /// Property TrackbackCount (int)
        /// </summary>
        public int TrackbackCount
        {
            get {  return this._trackbackCount; }
            set {  this._trackbackCount = value; }
        }
        #endregion

        #region Links
        public override string Url
        {
            get {return BlogUrls.Instance().HomePage(this.ApplicationKey);}
        }

        public string ReferralFilter
        {
            get{ return Url.ToLower().Replace("/default.aspx",string.Empty);}
        }
        #endregion

        #region Themes

        private static WeblogConfiguration config = WeblogConfiguration.Instance();
        private string theme = null;
        public string  Theme
        {
            get
            {
                if(theme == null)
                {
                    theme =  GetString("Theme",null);
                    
                    
                    if (Globals.IsNullorEmpty(theme) || !config.EnableThemes)
                        theme = config.DefaultTheme;
                }
                return theme;
            }

            set
            {

                //If updated value == Default Value, set to null. Otherwise, just update the inernal
                //store and set the local variable
                if(string.Compare(value,config.DefaultTheme) == 0)
                     SetExtendedAttribute("Theme", null);
                else
                     SetExtendedAttribute("Theme", value);

                theme = value;
            }
        }

        private string secondaryCSS = null;
        public string SecondaryCSS
        {
            get
            {
                if (secondaryCSS == null)
                {
                    secondaryCSS = GetString("SecondaryCSS", null);


                    if (Globals.IsNullorEmpty(secondaryCSS) || !config.EnableThemes)
                        secondaryCSS = config.DefaultSecondaryCSS;
                }
                return secondaryCSS;
            }
            set
            {
                //If updated value == Default Value, set to null. Otherwise, just update the inernal
                //store and set the local variable
                if (string.Compare(value, config.DefaultSecondaryCSS) == 0)
                    SetExtendedAttribute("SecondaryCSS", null);
                else
                    SetExtendedAttribute("SecondaryCSS", value);

                secondaryCSS = value;
            }
        }

        public string CSSOverride
        {
            get {  return GetString("CSSOverride",null); }
            set{ SetExtendedAttribute("CSSOverride",value); }            
        }

        #endregion

        public bool ValidateRatings(WeblogPost post)
        {
            if(!EnableRatingsOverride)
                return false;

            return post.EnableRatings;
        }

        public bool ValidateTrackBacks(WeblogPost post)
        {
            if(!EnableTrackbacksOverride)
                return false;

            return post.EnableTrackBacks;
        }

		public bool isAnonymousCommentsEnabled(WeblogPost post)
		{
			return (this.EnableAnonymousPosting && CSContext.Current.SiteSettings.EnableAnonymousUserPosting);
		}

        public bool EnableNewComments(WeblogPost post, User user)
        {
			if(!Permissions.ValidatePermissions(this,Permission.Reply,user))
				return false;

            if(!EnableCommentsOverride)
                return false;

            if(!EnableCommentsDefault)
                return false;

            if(post.IsLocked)
                return false;

            if(user.IsAnonymous && (!this.EnableAnonymousPosting || !CSContext.Current.SiteSettings.EnableAnonymousUserPosting))
                return false;

            return post.PostDate.AddDays(this.CommentExpirationDays) > DateTime.Now;
        }

		public bool IsPostModerated(WeblogPost post, User user)
		{
			// If the user is one of the blog owners, their comments are always approved
			if (post.Weblog.IsOwner(user) || user.IsBlogAdministrator)
				return false;
			
            if(this.ModerationTypeOverride == CommentModerationType.Ignore)
            {
                switch(post.ModerationType)
                {
                    case CommentModerationType.All:
                        return true;
                    case CommentModerationType.Anonymous:
                        return user.IsAnonymous;
                    case CommentModerationType.None:
                        return false;
                    default:
                        return true;
                }
            }
            else
            {
                switch(ModerationTypeOverride)
                {
                    case CommentModerationType.All:
                        return true;
                    case CommentModerationType.Anonymous:
                        return user.IsAnonymous;
                    case CommentModerationType.None:
                        return false;
                    default:
                        return true;
                }
            }
		}


    }
}
